Rhapsody Developer Release © Copyright 1998
by Apple Computer, Inc. All Rights Reserved.
This file contains release notes for the Developer Release 2 of the gdb and jdb command-line debuggers, and of the Project Builder visual debugging facilities. The section in this document are:
The gdb program is the GNU source-level Debugger. For more information, see the debugging documentation in /System/Documentation/Developer/Yellow Box/Reference/DevTools/Debugger. On Rhapsody, you can also refer to the gdb (1) manual page
The gdb debugger in this release (/usr/bin/gdb) is based on version 4.14 released by the Free Software Foundation (FSF). A newer version of gdb (/usr/bin/gdb-4.17), based on the gdb-971126 snapshot from Cygnus, is also available. Although still incomplete, this newer version of gdb offers better support areas such as signal handling, attaching to running processes, and dynamic library loading, as well as a number of bug fixes. If a feature in gdb doesn't work properly, you might try using gdb-4.17. For the most up-to-date information on gdb, see the Rhapsody Developer Release website in Apple Developer World
start()
for
shared-library loading
DYLD_LOAD_PATH
mechanism
The version of gdb for Yellow Box for Windows has not changed from the Developer Release.
gdb hangs (actually, the new Sybase CT-Lib adaptor blocks)
when you use the next
command to step over a line of
code which eventually causes a call to the Sybase client library.
More generally, when you are debugging a program that uses
multiple threads it's possible to create a situation in which a
deadlock will occur. Whenever the next
or step
commands are issued, gdb lets only the thread being
debugged execute. All other threads are suspended until the command
is completed. Therefore, if you attempt to step over a line of code
which tries to communicate with another thread, the program will
deadlock.
To deal with problems like this, a "run-all-threads" option has been added to gdb. This option controls whether all of the threads should execute while single-stepping. The default value for this option is "off". In order to prevent a deadlock like that described above, issue the following command in gdb:
set run-all-threads on
We recommend that you use this option only if you're experiencing a deadlock. Allowing other threads to execute while stepping through code can produce confusing results if, for example, the other threads are changing the values of global data.
gdb has been known to hang or crash if you run a program that uses a dynamic shared library (such as a framework or bundle), then recompile the dynamic shared library, and run the program again. If this happens, you should quit gdb and start a new debugging session every time you rebuild the library. You can use the .gdbinit file to help re-establish things such as breakpoints that you need in your debugging session.
Immediately after you start your program running under gdb, the program will start to load dynamic shared libraries, and gdb will begin reading symbols from these libraries. If you attempt to interrupt gdb by typing Control-C during this process, the debugger will be left in a confused internal state from which the only known recovery is to quit the debugger and start over.
When gdb debugs code without debugging symbols, it assumes
variables are of size sizeof(int)
. Setting or displaying
a BOOL (or any non-int) value will usually lead to incorrect results.
In particular, setting a BOOL value will cause the next three bytes
of memory to be overwritten. For example, if you have four BOOL
values declared, setting the first one will cause the next three to
acquire unexpected values. Of course, if you have only one BOOL
variable and you set it, whatever is next to it in memory is likely
to get trashed. This problem does not occur in code containing
debugging symbols as gdb knows exactly how big the variable in
question is.
This problem prevents setting the global debugging variables
declared in Foundation for debugging Objective-C programs; see:
/Library/Frameworks/Foundation.Framework/Headers/NSDebug.h
The workaround for this problem is to set the debugging variables via
the command-line or via the environment.
Due to the way that gdb interacts with the dynamic link
editor at startup, there is always a breakpoint inserted at
start()
+24. It is there to avoid a particularly nasty
race condition that prevents gdb from talking to the dynamic
link editor properly. After gdb stops at this breakpoint, you
must continue the target.
It has been observed that gdb sometimes gets confused when its target process creates a child process and that child process crashes. gdb incorrectly reports that parent process has crashed.
The Objective-C runtime system catches when messages are sent to some freed Objective-C objects; when this happens, a message like this appears in your console:
objc: FREED(id): message XXX sent to freed object=0x13d938
The runtime system calls abort()
. In this case
however, gdb is unable to print the backtrace beyond the third
stack frame. Thus it is not possible to determine the backtrace which
resulted in sending the message to a freed object. The workaround is
to set a breakpoint at _freedHandler
, which is a
function in the Objective-C runtime. This breakpoint is hit just
before the call to abort()
and gdb can provide a
valid backtrace.
The jdb command-line debugger from JavaSoft is included in the Developer Release 2 of both Rhapsody and Yellow Box for Windows. You can find the documentation for jdb Rhapsody at:
http://java.sun.com/products/jdk/1.1/docs/tooldocs/solaris/jdb.html
and for Windows at:
http://java.sun.com/products/jdk/1.1/docs/tooldocs/win32/jdb.html
Yellow Box Java applications, that is, those that subclass from
NSPureApplication and are started with the java
command,
do not work with jdb. For example, this command fails:
jdb com.apple.yellow.application.NSPureApplication -YBJavaApplicationPath /<wherever>/TextEdit.app"
Project Builder provides integrated, visual debugging of programs
through the Launcher panel ().
This panel can be used to run or debug executables built by your
project.
The following new features have been added to Project Builder for debugging since the Developer Release.
Just for your information: The Java Debugger is used if your application has the NSJavaAware key set in its Resources/Info.plist dictionary. The pb_makefiles set this key automatically if your project has any Java files in it.
Since the Java debugger is implemented as a set of threads in the Java VM, it is always active when the Java VM is running. It is possible to interact with the Java debugger even while the target is running. This is in contrast to gdb, which only processes commands when the target is stopped.
The process (application) being debugged is known as the debug target . The Java debugging code runs within the target Java VM. When gdb has stopped the target, it has also stopped the Java VM and hence the Java code can't run. So when the target stops in a Java breakpoint, Java stack frames are shown (there is no 'mixed' stack trace yet) and Java debugging information is available. When a gdb breakpoint is hit, C, Objective-C, and C++ information is available but no Java information is available.
Finally, here's how to get the gdb prompt when the
target is running. In the Launcher terminal window, press ^C
(Control-C) once or press the suppend button (). This will
stop the target and make the Java debugger active. To get to the
gdb prompt, press Control-C again and then press the
continue button (
); you will
now have the gdb prompt and the target is completely
stopped, including the Java VM.
These new bugs have appeared since the Developer Release.
The integrated Java debugger for use with Project Builder is not yet available on Windows. Check the Apple Developer World Web site for the latest status (http://devworld.apple.com/rhapsody/)
The stack back trace from the Java debugger includes only Java frames. Calls to native methods are not shown.
There is no debugging support for Java applets or 100% Pure Java applications.
You cannot set breakpoints in Java code before the debugger is running. As the Java VM starts up, there is a race condition between the starting of the debugger and the starting of the application. Therefore, some of your code will execute before the debugger becomes active and you are not able to set a breakpoint in this code.
Reference |
2224584 |
Problem |
No -g passed to javac when making target "debug". |
Description |
To get fully local symbols in .class files, the .java files in your project have to be compiled with the -g option. Unfortunately, due to a bug in the pb_makefiles, this is not done. |
Workaround |
In the Project Builder Build Panel, click the build
options button( |
This file summarizes the commands for the Java debugger, which is available through Project Builder. The complete set of commands is given below. Any unique command prefix is recognized (e.g. "du" for "dump"). If a prefix is not unique, the debugger will tell you. Several commands have short aliases (for example, "si" for "stepi" and "bt" for "backtrace"). The case of a command does not matter (for instance, "Break" = "break" = "BrEaK"). The case of arguments may matter (for example, class and file names must match case: "Exception" is not the same as "exception").
JavaBug>> mumble ERROR: No command prefix matches "mumble" b <fileName>:<lineNum> | <class>:<method> -- set a breakpoint backtrace -- backtrace: show stack info break <fileName>:<lineNum> | <class>:<method> -- set a breakpoint bt -- backtrace: show stack info catch className -- catch exceptions for exception class className clear Num -- clear (delete) breakpoint number Num continue -- continue execution from a breakpoint dir [path] -- get or set dir(ectory) search path disable Num -- disable breakpoint number Num down [Num] -- set default frame down Num|1 frames drop className -- drop (stop catching) exceptions for class className dump object -- print object's struct(ure) enable Num -- enable breakpoint number Num finish -- step Out (finish executing current stack frame) frame [Num] -- show stack frame info for stack[Num] or current frame getprop name -- get system property group [groupName] -- if groupName then set curent thread group, else show information for thread groups and their threads list -- list source lines around current frame (if available) next -- step Over<p* object -- print object's struct(ure) po object -- invoke object's toString() method print object -- invoke object's toString() method resume -- resume all threads si -- execute a single bytecode instruction (step into) step -- step Into stepi -- execute a single bytecode instruction (step into) suspend -- suspend all threads thread threadNum -- set current thread to threadNum up [Num] -- set default frame up Num|1 frames
In the Java debugger, there is a current thread group and a current thread. When an exception occurs, the current thread is reset. The current thread group is always the thread group containing the current thread.
Group [groupName] This command lists thread groups and threads. If a groupName is given, the current thread group is set to that name. To avoid confusion ,thread groups are referred to by name, while threads within a group are referred to by number.
Thread threadNum This command sets the thread within the current thread group. To find out the current group and thread, type group.
JavaBug>> group
Group: system 1 Finalizer thread cond. waiting 2 JavaBug cond. waiting 3 Debugger agent running 4 Breakpoint handler cond. waiting 5 Step handler cond. waiting 6 Agent input cond. waiting 7 main suspended< Group: main 1 main suspended CURRENT GROUP is "system" CURRENT THREAD within the group is "main" JavaBug>> thread 6 Current thread now Agent input, state=cond. waiting
Backtrace This command displays the contents of the current thread's Java stack. (Currently, only Java stack frames are printed. No "native" (non-Java) frames appear). An alias for backtrace is bt.
JavaBug>> bt [0] java.io.PipedInputStream.read (PipedInputStream:201) pc = 80 [1] java.io.PipedInputStream.read (PipedInputStream:242) pc = 43 [2] java.io.BufferedInputStream.fill (BufferedInputStream:135) pc = 164 [3] java.io.BufferedInputStream.read (BufferedInputStream:162) pc = 12 [4] java.io.FilterInputStream.read (FilterInputStream:81) pc = 4 [5] sun.tools.debug.AgentIn.run (AgentIn:46) pc = 20 [6] java.lang.Thread.run (Thread:474) pc = 11
Stack inspection commands (frame, up, down, print, dump) require that the thread being inspected is suspended. Threads are suspended by hitting a breakpoint, or by the suspend command.
Frame [frameNum] This command displays the arguments and local variables for the current frame or the frame number frameNum . Frame numbers are absolute and are the numbers displayed in the backtrace. Note that Java code must have been compiled with javac's -g flag or local and argument information is not available to the debugger. The frame command resets the current frame.
JavaBug>> backtrace [0] com.apple.alpha.core.MutableDictionary.<init> (MutableDictionary:213) pc = 0 [1] Document.setRichText (Document:534) pc = 10<[2] Document.toggleRich (Document:596) pc = 69 JavaBug>> frame 1 [1] setRichText(flag=true) <local> view = <NSTextView: 0x194b8c0>Frame = {{0.00, 0.00}, {490.00, 420.00}}, Bounds = {{0.00, 0.00}, {490.00, 420.00}} Horizontally resizable: NO, Vertically resizable: YES MinSize = {490.00, 420.00}, MaxSize = {340282346638528859811704183484516925440.00, 340282346638528859811704183484516925440.00}
Up [numFrames] This command resets the current frame up (toward older frames => higher frame numbers) relative to the current frame. If numFrames is not given, 1 is used.
Down [numFrames] This command resets the current frame down (toward newer frames => lower frame numbers) relative to the current frame. If numFrames is not given, 1 is used.
Print object This
command prints the object object by calling its
toString()
method. An alias for print is po (for
Print Object).
JavaBug>> po view view = <NSTextView: 0x194b8c0>Frame = {{0.00, 0.00}, {490.00, 420.00}}, Bounds = {{0.00, 0.00}, {490.00, 420.00}} Horizontally resizable: NO, Vertically resizable: YES MinSize = {490.00, 420.00}, MaxSize = {340282346638528859811704183484516925440.00, 340282346638528859811704183484516925440.00}
Dump object This command prints the object object structurally. An alias for dump is p* (from gdb usage for Print *=reference).
JavaBug>> p* view view = (com.apple.alpha.app.TextView)0x3bc0c0 { private int instance = 26523840 } JavaBug>> p* 0x3bc0c0 0x3bc0c0 = (com.apple.alpha.app.TextView)0x3bc0c0 { private int instance = 26523840 }
(In the above case, the object is obviously a native object with a peer class.)
List This command displays source text for the current frame--when it can find it. (Note the dir command, below).
JavaBug>> break Document:setRichText Set breakpoint 2000 in method: setRichText at line 533 in file "Document.java" JavaBug>> cont JavaBug>> // breakpoint hit because of user action Broken at 533 in "Document.java" JavaBug>> list File: "Document.java" 529 return layoutManager().hyphenationFactor(); 530 } 531 532 public void setRichText(boolean flag) { 533 => TextView view = firstTextView(); 534 MutableDictionary textAttributes = new MutableDictionary(2); 535 536 isRichText = flag; 537
Suspend This command suspends all Java
threads (which are not involved in debugging).
Resume This command resumes all Java
threads (which are not involved in debugging).
Break [fileName:lineNumber] This command sets
a breakpoint in file fileName at line
lineNumber . An alias for break is b. With
no arguments, it prints the current breakpoints.
Break [ClassName:methodName] This command sets a breakpoint at the start of method methodName in class ClassName . An alias for break is b. With no arguments, it prints the current breakpoints.
JavaBug>> break Document:setRichText Set breakpoint 2000 in method: setRichText at line 533 in file "Document.java" JavaBug>> break break <fileName>:<lineNum> | <class>:<method> -- set a breakpoint 2000 Document.java:533 JavaBug>> disable 2000 JavaBug>> break break <fileName>:<lineNum> | <class>:<method> -- set a breakpoint 2000 Document.java:533 [disabled]
Clear [breakNum] This command clears (forgets) the breakpoint numbered breakNum . With no argument, it prints the current breakpoints.
Disable [breakNum] This command disables, but does not clear, the breakpoint numbered breakNum .
Enable [breakNum] This command (re)enables the breakpoint numbered breakNum .
Continue When a thread is broken, this command continues (resumes) execution of that thread.
Step This command steps forward a line of code. If the code is a call, it steps into the call. If the call is to "native" (non-java) code, it steps over the code (acts like next ). If the step returns to native code, it acts like continue .
Setpi This command steps forward by a single bytecode instruction. It otherwise acts like step . (Currently, there is no command to display the bytecodes. Use "javap -c classFile " to see the bytecodes).
Next This command steps forward a line of code. If the code is a call, it steps over the call. If the step returns to native code, it acts like continue .
Finish This command steps to the end of the code in the current stack frame. (also know as "step out").
Catch ExceptionClass This command causes exceptions for class ExceptionClass and all its subclasses to act like a breakpoint. (At this time one cannot step through exception code one can only inspect the stack and continue ).
Drop ExceptionClass This command is the inverse of catch. The system will no longer break when an exception of class ExceptionClass is thrown.
Dir [newClassPath] This command prints or sets the CLASSPATH used to search for debug and source information (e.g. for the list and frame commands).
GetProp [propName] This command prints the value for the specified property or all properties of the Java VM. JVM properties cannot be changed.
JavaBug>> getprop user.home /Local/Users/kend JavaBug>> getprop Property Names: user.language = "en" java.home = "/Library/Frameworks/JavaVM.framework/Home" awt.toolkit = "com.apple.rhapsody.awt.RToolkit" file.encoding.pkg = "sun.io" java.version = "internal_build:kend:03/05/98-09:08" file.separator = "/" line.separator = " file.encoding = "MacRoman" java.compiler = "jitc_ppc" java.protocol.handler.pkgs = "com.apple.net.protocol" java.vendor = "Apple Computer, Inc." user.timezone = "PST" user.name = "kend" os.arch = "ppc" os.name = "Rhapsody" java.vendor.url = "http://www.apple.com/" user.dir = "/Local/Users/kend/Projects/TextEdit" java.class.path = "/Local/Users/kend/Projects/TextEdit/TextEdit.app/Resources/Java/.:.:/Local/Users/kend/jdk20build/build/classes:/System/Library/Java:/Library/Frameworks/JavaVM.framework/Classes/classes.jar:/Library/Frameworks/JavaVM.framework/Classes/awt.jar" java.class.version = "45.3" os.version = "Premier Release" path.separator = ":" user.home = "/Local/Users/kend"